package com.zhanghp.class03;

import com.zhanghp.refer.DoubleNode;
import com.zhanghp.refer.ListNode;

import java.util.List;

import static com.zhanghp.refer.ListNode.*;
import static com.zhanghp.refer.DoubleNode.*;

/**
 * <h1>单链表&双节点链表逆序</h1>
 *
 * @author zhanghp
 * @date 2023-08-22 20:48
 */
public class Code01_ReverseList {


//    public static void main(String[] args) {
//        ListNode ListNode = generateRandomLinkedList(10, 10);
//        ListNode copy = copy(ListNode);
//        printLinkedList(ListNode);
//
//        printLinkedList(reverseLinkedListForZuo(copy));
////        reverseLinkedListForZuo(copy);
////        printLinkedList(copy);
////        capilerCopy();
//    }

    public static void main(String[] args) {
        int len = 50;
        int value = 100;
        int testTime = 100000;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {

            DoubleNode node3 = generateDoubleLinkedList(len, value);
            List<Integer> list3 = getDoubleListOriginOrder(node3);
            node3 = reverseDoubleLinkedList(node3);
            if (!checkDoubleListReverse(list3, node3)) {
                System.out.println("Oops3!");
            }

            DoubleNode node4 = generateDoubleLinkedList(len, value);
            List<Integer> list4 = getDoubleListOriginOrder(node4);
            node4 = reverseDoubleLinkedList(node4);
            if (!checkDoubleListReverse(list4, node4)) {
                System.out.println("Oops4!");
            }

        }
        System.out.println("test finish!");

    }




    public static DoubleNode reverseDoubleLinkedList(DoubleNode doubleListNode){
        if (doubleListNode == null) {
            return null;
        }
        DoubleNode pre = null;
        DoubleNode n = doubleListNode.next;
        while (n != null) {
            doubleListNode.last = n;
            doubleListNode.next = pre;
            pre = doubleListNode;
            doubleListNode = n;
            n = doubleListNode.next;
        }
        return pre;
    }

    public static DoubleNode reverseDoubleList(DoubleNode head) {
        DoubleNode pre = null;
        DoubleNode next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            head.last = next;
            pre = head;
            head = next;
        }
        return pre;
    }

    // ===================>单节点

    private static ListNode copy(ListNode ListNode){
        if (ListNode == null) {
            return null;
        }
        ListNode cur = ListNode.next;
        ListNode head = new ListNode(ListNode.val);
        ListNode result = head;
        while (cur != null) {
            result.next =  new ListNode(cur.val);
            cur = cur.next;
            result = result.next;

        }
        return head;
    }
    /**
     * 左神：将LinkedeList反转
     *
     * @param head 需要反转的头节点
     */
    public static ListNode reverseLinkedListForZuo(ListNode head){
        ListNode pre = null;
        ListNode next = null;
        while (head != null) {
            // 把head.next指向的节点，赋予next
            next = head.next;
            // head.next的地址引用变更，指的是head这个节点内部属性next指向变更，并不影响下一节点
            head.next = pre;
            pre = head;
            head =next;
        }
        return pre;
    }


    public static ListNode reverseLinkedListForMine1(ListNode ListNode){
        if (ListNode == null || ListNode.next == null) {
            return ListNode;
        }
        ListNode pre = null;
        ListNode cur = ListNode;
        ListNode next = ListNode.next;
        do{
            cur.next = pre;
            pre = cur;
            cur = next;
            if (next != null) {
                next = next.next;
            }
        }while (cur != null);
        return pre;
    }

    /**
     * 自己写...
     * <p>
     *     为什么要返回值，而不是直接赋值？
     * </p>
     * <p>
     *     在Java中，当你将一个对象传递给方法作为参数时，实际上传递的是对象的引用（或者说内存地址），
     *     而不是对象本身。因此，如果你在方法中修改了对象的状态（例如修改对象的属性），那么这些修改会在方法外部持续存在。
     *     但是，如果你在方法内部为对象分配了一个新的实例（即对该对象进行重新赋值），这个修改不会影响到原始的对象。
     * </p>
     *
     * @param ListNode 节点
     * @return
     */
    public static ListNode reverseLinkedListForMine2(ListNode ListNode){
        if (ListNode == null) {
            return null;
        }
        ListNode pre = null;
        ListNode cur = ListNode;
        ListNode temp = null;
        do{
            temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;

        }while (cur != null);
        return pre;
    }

    /**
     * 对数器 -------------------------------------------------》
     */
    @SuppressWarnings("all")
    private static void capilerCopy(){
        int size = ((int) (Math.random() * 1_000));
        int maxval = ((int) (Math.random() * 1_000));
        int test_time = 10_000;
        System.out.println("测试开始");
        for (int i = 0; i < test_time; i++) {
            ListNode ListNode = generateRandomLinkedList(size, maxval);
            ListNode copy = copy(ListNode);
            if (ListNode == null && copy != null) {
                System.out.println("Fuck the null");
                return;
            }
            if (copy == null && ListNode != null) {
                System.out.println("Fuck the copy");
                return;
            }
            while (ListNode != null){
                if (copy == null) {
                    System.out.println("Fuck the while, copy is null");
                    return;
                }
                if (ListNode.val != copy.val) {
                    System.out.println("Fuck the val");
                    return;
                }
                ListNode = ListNode.next;
                copy = copy.next;

            }
        }
        System.out.println("测试结束");

    }
}
